=begin pod :tag<convert>

=TITLE 5to6-perlop

=SUBTITLE Perl 5 to Perl 6 guide - operators

=head1 DESCRIPTION

A (hopefully) comprehensive list of Perl 5 operators with their Perl 6
equivalents with notes on variations between them where necessary.

=head1 NOTE

This document I<does not> explain the operators in detail.
This document is an attempt to guide you from the operators in Perl 5's perlop document to
their equivalents in Perl 6. For full documentation on the Perl 6
equivalents, please see the L<Perl 6 documentation|/language/operators>.

=head2 Operator Precedence and Associativity

The operator precedence table is somewhat different in Perl 6 than it is in
Perl 5, so it will not be detail  here. If you need to know the precedence and
associativity of a given operator in Perl 6, refer to
L<Operator Precedence|/language/operators#Operator_Precedence>.

=head2 Terms and List Operators

The things listed in Perl 5's perlop document as unary and list operators in
this section tend to be things that can also be thought of as functions, such
as C<print> and C<chdir>. As such, you can find information about them in
L<5to6-perlfunc.pod6|/language/5to6-perlfunc>. Parentheses are still used for grouping.

=head2 The Arrow Operator

As you typically will not be using references in Perl 6, the arrow is
probably less useful as a dereferencing operator. If you do need to
dereference something, however, the arrow is the dot. It is also the dot
for method calls. So, Perl 5's C<< $arrayref->[7] >> becomes
C<$arrayref.[7]> in Perl 6 and, similarly, C<< $user->name >> becomes
C<$user.name>. The C<< => >> arrow is used for constructing Pairs, see
L<Pair term documentation|/language/terms#Pair>.

=head2 Auto-increment and Auto-decrement

Work as in Perl 5. The one possible caveat is that they function by
calling the C<succ> method for C<++> and the C<pred> method for C<-->.
For builtin numeric types, this is unlikely to do something unusual, but
custom types can define their own C<succ> and C<pred> methods, so in
those cases, you should probably take note of what C<++> and C<--> will
I<actually> do.

=head2 Exponentiation

Works as you would expect. The caveat in Perl 5's perlop about C<**>
binding more tightly than unary minus (i. e. "-2**4" evaluates as "-(2**4)"
rather than "(-2)**4)") is also true for Perl 6.

=head2 Symbolic Unary Operators

As in Perl 5, unary C<!> and C<-> do logical and arithmetic negation,
respectively. C<?^> is used for bitwise logical negation, which the
documentation indicates is equivalent to C<!>. It may be relevant to
note that these coerce their arguments to C<Bool> and C<Numeric>,
respectively.

Unary C<~> is the string context operator in Perl 6, so use prefix C<+^>
for bitwise integer negation. Assumes two's complement.

C<+> I<does> have an effect in Perl 6, coercing its argument to the
Numeric type.

Unary C<\> is no more. If you really want to take a reference to an existing
named variable, you can use item context, like so: C<$aref = item(@array)>
You can get a reference to a named subroutine by using the C<&> sigil: C<$sref
= &foo> Anonymous arrays, hashes, and subs return their references during
creation I<right away>.

=head2 Binding Operators

C<=~> and C<!~> have been replaced by C<~~> and C<!~~>, respectively. Those of
you who consider smart matching broken in Perl 5 will be happy to hear that it
works much better in Perl 6, as the stronger typing means less guesswork.

=head2 Multiplicative Operators

Binary C<*>, C</>, and C<%> do multiplication, division, and modulo,
respectively, as in Perl 5.

Binary C<x> is slightly different in Perl 6, and has a companion.
C<print '-' x 80;> gives you a string of 80 dashes, but for the Perl 5
behavior of C<@ones = (1) x 80;> giving you a list of 80 "1"s, you would
use C<@ones = 1 xx 80;>.

=head2 Additive Operators

Binary C<+> and C<-> do addition and subtraction, respectively, as you would
expect.

As C<.> is the method call operator, so binary C<~> acts as the
concatenation operator in Perl 6.

=head2 Shift Operators

C« << » and C« >> » have been replaced by C<< +< >> and C<< +> >>.

=head2 Named Unary Operators

As noted above, you'll find these in L<5to6-perlfunc.pod6|/language/5to6-perlfunc>.

=head2 Relational Operators

These all work as in Perl 5.

=head2 Equality Operators

C<==> and C<!=> both work as in Perl 5.

C<< <=> >> and C<cmp> have different behavior in Perl 6. C<< <=> >> does
a numeric comparison, but returns C<Order::Less>, C<Order::Same>, or
C<Order::More> instead of Perl 5's C<-1>, C<0>, or C<1>. To get the Perl
5 behavior (with the change that it returns the C<Order> objects, rather
than integers) of C<cmp>, you would use the C<leg> operator.

C<cmp> does either C<< <=> >> or C<leg>, depending on the existing type
of its arguments.

C<~~> is the smart match operator as in Perl 5, but it's also I<just>
the match operator in Perl 6, as noted above. For how smart matching
works in Perl 6, see L<https://design.perl6.org/S03.html#Smart_matching>.

=head2 Smartmatch Operator

See the entry on C<~~> directly above.

=head2 Bitwise And

Binary C<&> is C<+&> in Perl 6.

=head2 Bitwise Or and Exclusive Or

Bitwise OR has changed from C<|> in Perl 5 to C<+|> in Perl 6.
Similarly, bitwise XOR C<^> is C<+^>

=head2 C-style Logical And

Unchanged.

=head2 C-style Logical Or

Unchanged.

=head2 Logical Defined-Or

Remains in Perl 6 as C<//>. Returns the first defined operand, or else
the last operand. Also, there is a low precedence version, called
C<orelse>.

=head2 Range Operators

In list context, C<..> operates as the range operator and should not
need to be changed. That said, there are exclusionary range operators
that may be useful. These are:

=item infix C<..^> which excludes the endpoint;
=item infix ^.. which excludes the starting point;
=item infix C<^..^> which excludes both the starting and ending points;
=item prefix C<^> which starts from zero excluding the endpoint.

The following example shows the effects of all the above range operators
(please note parentheses are used only to allow the method call):

=begin code
(1..^5).list;  # (1 2 3 4)
(1^..5).list;  # (2 3 4 5)
(1^..^5).list; # (2 3 4)
(^5).list;     # (0 1 2 3 4)
=end code

In Perl 5, in scalar context, the operators C<..> and C<...> work
as flip-flop operators, even if they are little-known and probably
less used. Those operators have been replaced in Perl 6
by L<ff|/routine/ff> and L<fff|/routine/fff> respectively.

=head2 Conditional Operator

The conditional operator C<? :> has been replaced
by C<?? !!>:

=for code :lang<perl5>
$x = $ok  ? $yes  : $no;  # Perl 5
=for code :preamble<my $x;my $ok;my $yes;my $no>
$x = $ok ?? $yes !! $no;  # Perl 6

=head2 Assignment Operators

Although not fully documented, S03 indicates that the mathematical and
logical assignment operators should work as you would expect. The one
noticeable change is that C<.=> calls a mutating method on the object on
the left, while C<~=> is the string concatenation assignment, as you
might expect with the changes in C<.> and C<~>. Also, the bitwise
assignment operators are likely not separated into numeric and string
versions (C<&=>, etc., vs. C<&.=>, etc.), as that feature is currently
experimental in Perl 5 itself - although, again, this is not
specifically documented.

=head2 Comma Operator

The comma operator works mostly as expected, but technically it creates
L<Lists|/type/List>) or separates arguments
in function calls. Also, there is a C<:> variant that turns function
calls into method calls - see
L<this page|/language/operators#infix_%3A>.

The C<< => >> operator works similarly to the Perl 5 "fat comma"
behavior in that it allows an unquoted identifier on its left side, but
in Perl 6 constructs Pair objects, rather than just functioning as a
separator. If you are trying to just literally translate a line of Perl
5 code to Perl 6, it should behave as expected.

=head2 List Operators (Rightward)

Like the Named Unary Operators, you'll find these discussed in
L<5to6-perlfunc.pod|/language/5to6-perlfunc>.

=head2 Logical Not

The lower precedence version of C<!>. As with C<!>, coerces its argument
to C<Bool>.

=head2 Logical And

Lower precedence version of C<&&> as in Perl 5.

=head2 Logical or and Exclusive Or

C<or> is the low precedence version of C<||>. The documentation lists an
C<xor>, but does not actually document it.

Additionally, there is a low precedence version of C<//>, called
C<orelse>.

=head2 Quote and Quote-like Operators

For all the gory details on quoting constructs, see
L<quoting|/language/quoting>.

There is a quoting operator that allows absolute literal strings: C<Q> or
C<｢…｣>, although the latter might be difficult to find on your keyboard,
depending on your keyboard... Backslash escapes do I<not> apply in C<Q> quoted
strings. E. g. C<Q{This is still a closing curly brace → \}> renders "This is still a
closing curly brace → \".

C<q> does what you expect, allowing backslash escapes. E. g. C<q{This is
not a closing curly brace → \}, but this is → }> returning "This is
not a closing curly brace → }, but this is →". As in Perl 5, you can
get this behavior with single quotes.

C<qq> allows interpolation of variables. However, by default, only
scalar variables are interpolated. To get other variables to
interpolate, you need to put square brackets after them. E. g. C<< @a =
<1 2 3>;say qq/@a[] example@example.com/; >> results in "1 2 3
example@example.com". Hashes interpolate in a possibly unexpected
manner: C<< %a = 1 => 2, 3 => 4;say "%a[]"; >> results in a space
separating the pairs and tabs separating the key from the value in each
pair (apparently). You can also interpolate Perl 6 code in strings using
curly braces. For all the details, see
L<Interpolation|/language/quoting#Interpolation%3A_qq>.

C<qw> works as in Perl 5, and can also be rendered as C<< <...> >>. E.
g. C<qw/a b c/> is equivalent to C<< <a b c> >>.

There is also a version of C<qw> that interpolates, which is C<qqw>. So
C<my $a = 42;say qqw/$a b c/;> gives you "42 b c".

Shell quoting is available through C<qx>, but you should note that
backticks do not do shell quoting as in Perl 5, and Perl variables are
I<not> interpolated in C<qx> strings. If you need to interpolate Perl
variables in a shell command string, you can use C<qqx> instead.

The C<qr> operator is gone from Perl 6.

C<tr///> works similarly to how it
does in Perl 5. The one caveat is that ranges are specified differently.
Instead of using a range "a-z", you would use "a..z", i. e. with Perl's
range operator. C<tr///> has a method version, which is better
documented, called C<.trans>. C<.trans> uses a list of pairs, as
follows: C<< $x.trans(['a'..'c'] => ['A'..'C'], ['d'..'q'] =>
['D'..'Q'], ['r'..'z'] => ['R'..'Z']); >> A much more extensive
description of the uses of C<.trans> can be found at
L<https://design.perl6.org/S05.html#Transliteration>. The C<y///>
equivalent has been done away with.

Heredocs are specified differently in Perl 6. You use C<:to> with your quoting
operator, e. g. C<q:to/END/;> would start a heredoc ending with "END".
Similarly, you get escaping and interpolation based on your quoting operator,
i. e. literals with C<Q>, backslash escapes with C<q>, and interpolation with
C<qq>.

=head2 I/O Operators

The full details on Input/Output in Perl 6 can be found at
L<io|/language/io>.

As C<< <...> >> is the quote-words construct in Perl 6, C<< <> >> is not
used for reading lines from a file. You can do that by either making an
C<IO> object from a file name or using an open filehandle and then, in
either case, calling C<.lines> on it. I. e. either C<my @a =
"filename".IO.lines;> or C<my $fh = open "filename", :r;my @a =
$fh.lines;> (In the latter case, we are using C<:r> to specifically open
the file for reading). To do this in an iterative manner, you can use a
C<for> loop this way:

=begin code
for 'huge-csv'.IO.lines -> $line {
    # Do something with $line
}
=end code

Note the use of C<< -> >> there. That's part of the Block syntax, and in
Perl 6 is needed for C<if>, C<for>, C<while>, etc.

If you want to slurp the entire file into a scalar, you would - surprise! -
use the C<.slurp> method. For instance

=begin code
my $x = "filename".IO.slurp;
# ... or ...
my $fh = open "filename", :r;
my $x = $fh.slurp;
=end code

As noted in L<5to6-perlvar.pod|/language/5to6-perlvar>, the C<ARGV> magic input filehandle has
been replaced by C<$*ARGFILES>, and the C<@ARGV> array of command line
arguments has been replaced by C<@*ARGS>.

=head2 No-ops

Although it's not specifically documented, C<1 while foo();> appears to
work in this sense.

=head2 Bitwise String Operators

Documented individually above, but to summarize...

Bitwise integer negation is prefix C<+^>. Bitwise boolean
negation is C<?^>.

Bitwise and is C<+&>.

Bitwise integer or is C<+|>. Bitwise integer xor is infix C<+^>. Bitwise
boolean or is C<?|>.

Left shift and right shift are C<< +< >> and C<< +> >>.

=end pod

# vim: expandtab softtabstop=4 shiftwidth=4 ft=perl6
